#include "DS1302.h"
#include <REGX52.H>
#include "LCD1602.h"


sbit CE = P3^5;
sbit SCLK = P3^6;
sbit IO = P3^4;

// 年，月，日，时，分，秒，日期
unsigned char time[7] = {24,11,14,21,20,51,4};
unsigned char time_cmd[6] = {YEARWR,MONWR,DATEWR,HOURWR,MINWR,SECWR};

// 对DS1302的一些寄存器进行初始化
void DS1302_Init()
{
	// 单片机上电后默认给各个口设置为高电平
	CE = 0;
	SCLK = 0;
}

// cmd：命令字
// Data：写入数据
void DS1302_WriteByte(unsigned char cmd,unsigned char Data)
{
	int i;
	// CE有效，写入才有效
	CE = 1;
	// 1.根据时序图，先写命令字cmd，再写数据Data
	// 取出cmd的一个bit，SCLK为上升沿写入数据到IO口
	for(i = 0; i < 8; i++)
	{
		IO = cmd & (0x01 << i);
		SCLK = 1;
		SCLK = 0;
	}
	// 2.根据时序图，写入Data
	for(i = 0; i < 8; i++)
	{
		IO = Data & (0x01 << i);
		SCLK = 1;
		SCLK = 0;
	}
	CE = 0;
}


// cmd：命令字
// 返回值：读取的数据
unsigned char DS1302_ReadByte(unsigned char cmd)
{
	// 观察对应时序图，我们可以发现实际的上升沿只有15个
	// 即DS1302内部，当写入cmd最后一个bit后，立马可以读取数据了
	// 我们得把 cmd和Data分开，一开始需要给一个下降沿，再给上升沿
	int i;
	unsigned char Data = 0x00;
	CE = 1;
	// 复用写的命令字
	cmd |= 1;
	for(i = 0; i < 8; i++)
	{
		IO = cmd & (0x01 << i);
		SCLK = 0;
		SCLK = 1;
	}
	// 此时SCLK 处于高电平，且DS1302给出来的数据已经在IO口上了
	// 按SCLK = 1，0读取，最后读取完后，和时序图一致
	for(i = 0; i < 8; i++)
	{
		SCLK = 1;
		SCLK = 0;
		if(IO) Data |= (0x01 << i);
	}
	CE = 0;
	IO = 0; //读取后将IO设置为0，否则循环内连续读出的数据会出错
	return Data;
}





void Write_Time()
{
	int i;
	
	DS1302_WriteByte(WP,0x00);
	for(i = YEAR_IDX; i < DAY_IDX;i++)
	{
		DS1302_WriteByte(time_cmd[i],time[i] / 10 * 16 + time[i] % 10);
	}
	DS1302_WriteByte(WP,0x80);
	
}

void Read_Time()
{
	unsigned char BCD_Data;
	int i;
	for(i = YEAR_IDX; i <  DAY_IDX;i++)
	{
		BCD_Data = DS1302_ReadByte(time_cmd[i]);
		time[i] =  BCD_Data / 16 * 10 + BCD_Data % 16;
	}
	
}

